from django.shortcuts import render
from django.views.generic import View
from django.http import JsonResponse
from goods.models import GoodsSKU
from django_redis import get_redis_connection
import json


class DeleteCartView(View):
    """删除购物车中的商品"""
    def post(self, request):
        # 接收参数：sku_id
        sku_id = request.POST.get('sku_id')
        user = request.user
        # 校验参数：not，判断是否为空
        if sku_id is None:
            return JsonResponse({'code': 1, 'message': '参数不正确'})

        # 判断用户是否登录
        if user.is_authenticated():

            # 如果用户登陆，删除redis中购物车数据
            redis_coon = get_redis_connection('default')
            redis_coon.hdel('cart_%s' % user.id, sku_id)
            return JsonResponse({'code': 0, 'message': '删除成功'})

        # 如果用户未登陆，删除cookie中购物车数据
        else:
            cart_json = request.COOKIES.get('cart')
            if cart_json:
                cart_dict = json.loads(cart_json)
                if sku_id in cart_dict:
                    del cart_dict[sku_id]

                response = JsonResponse({'code': 0, 'message': '删除成功'})
                response.set_cookie('cart', json.dumps(cart_dict))
                return response


class UpdateCartView(View):
    """更新购物车 数量"""

    def post(self, request):
        # 获取参数：sku_id, count
        sku_id = request.POST.get('sku_id')
        count = request.POST.get('count')
        # 校验参数all()
        if not all([sku_id, count]):
            return JsonResponse({'code': 1, 'message': '参数错误'})

        # 判断商品是否存在
        try:
            sku = GoodsSKU.objects.get(id=sku_id)
        except GoodsSKU.DoesNotExist:
            return JsonResponse({'code': 2, 'message': '商品不存在'})

        # 判断count是否是整数
        try:
            count = int(count)
        except Exception:
            return JsonResponse({'code': 3, 'message': '数量错误'})

        # 判断库存
        if count > sku.stock:
            return JsonResponse({'code': 4, 'message': '库存不足'})
        user = request.user
        # 判断用户是否登陆
        if user.is_authenticated():
            # 如果用户登陆，将修改的购物车数据存储到redis中
            redis_coon = get_redis_connection('default')
            redis_coon.hset('cart_%s' % user.id, sku_id, count) # 把原来的值铺盖掉  等幂
            return JsonResponse({'code': 0, 'message': '成功'})

        # 如果用户未登陆，将修改的购物车数据存储到cookie中
        else:
            cart_json = request.COOKIES.get('cart')
            if cart_json is not None:
                cart_dcit = json.loads(cart_json)
            else:
                cart_dcit = {}

            cart_dcit[sku_id] = count
            new_dict = json.dumps(cart_dcit)
            # 响应结果
            response = JsonResponse({'code': 0, 'message': '成功'})
            response.set_cookie('cart', new_dict)

            return response


# 展示购物车数据视图
class CartInfoView(View):
    """获取购物车数据"""

    def get(self, request):
        """提供购物车页面：不需要请求参数"""

        # 查询购物车数据
        # 如果用户登陆从redis中获取数据
        if request.user.is_authenticated():
            # 创建redis连接对象
            redis_conn = get_redis_connection('default')
            user_id = request.user.id
            # 获取所有数据
            cart_dict = redis_conn.hgetall('cart_%s' % user_id)
        else:
            # 如果用户未登陆从cookie中获取数据
            cart_json = request.COOKIES.get('cart')
            # 判断用户是否操作过购物车cookie
            if cart_json is not None:
                cart_dict = json.loads(cart_json)
            else:
                cart_dict = {}

        # 保存遍历出来的sku
        skus = []
        # 总金额
        total_amount = 0
        # 总数量
        total_count = 0

        # 遍历cart_dict，形成模板所需要的数据
        for sku_id, count in cart_dict.items():
            # 查询商品sku
            try:
                sku = GoodsSKU.objects.get(id=sku_id)
            except GoodsSKU.DoesNotExist:
                # 商品不存在，跳过这个商品，继续遍历
                continue

            # 将count转成整数，因为redis中取出的count不是整数类型的
            count = int(count)

            # 计算总价
            amount = sku.price * count
            # 将需要展示的数据保存到对象中
            sku.amount = amount
            sku.count = count

            # 生成模型列表
            skus.append(sku)

            # 计算总金额
            total_amount += amount
            # 计算总数量
            total_count += count

        # 构造上下文
        context = {
            'skus': skus,
            'total_amount': total_amount,
            'total_count': total_count
        }

        return render(request, 'cart.html', context)


class AddCartView(View):
    """添加到购物车"""

    def post(self, request):
        """"""
        # 接收数据：user_id，sku_id，count
        user_id = request.user.id
        sku_id = request.POST.get('sku_id')
        count = request.POST.get('count')

        # 校验参数all()

        if not all([sku_id, count]):
            return JsonResponse({'code': 2, 'message': '信息不全!'})

        # 判断商品是否存在
        try:
            sku = GoodsSKU.objects.get(id=sku_id)
        except GoodsSKU.DoesNotExist:
            return JsonResponse({'code': 3, 'message': '商品不存在'})

        # 判断count是否是整数
        try:
            count = int(count)
        except Exception:
            return JsonResponse({'code': 4, 'message': '商品数量错误'})

        if request.user.is_authenticated():
            # 操作redis数据库存储商品到购物车
            redis_coon = get_redis_connection('default')
            origin_count = redis_coon.hget('cart_%s' % user_id, sku_id)
            if origin_count is not None:
                count += int(origin_count)

            # 判断库存
            if count > sku.stock:
                return JsonResponse({'code': 5, 'message': '库存不足'})

            # 存储到redis
            redis_coon.hset('cart_%s' % user_id, sku_id, count)

            # 为了配合模板中js交互并展示购物车的数量，在这里需要查询一下购物车的总数
            cart_num = 0
            redis_dict = redis_coon.hgetall('cart_%s' % user_id)
            for val in redis_dict.values():
                cart_num += int(val)

            # json方式响应添加购物车结果
            return JsonResponse({'code': 0, 'message': '添加购物车成功', 'cart_num': cart_num})
            # 判断用户是否登陆
        else:
            """未登录用户 数据存储在cookie"""

            # 1.先从cookie中，获取当前商品的购物车记录 (cart_json)
            cart_json = request.COOKIES.get('cart')

            # 如果(cart_json)存在就把它转成字典(cart_dict)
            if cart_json:
                cart_dict = json.loads(cart_json)
            # 如果(cart_json)不存在就定义空字典(cart_dict)
            else:
                cart_dict = {}

            # 判断要添加的商品在购物车中是否存在
            if sku_id in cart_dict:
                # 如果存在就取出源有值，并进行累加
                origin_count = cart_dict[sku_id]
                count += origin_count

            # 判断库存
            if count > sku.stock:
                return JsonResponse({'code': 5, 'message': '库存不足'})

            # 如果不存在就直接保存商品数量
            cart_dict[sku_id] = count

            # 计算购物车数量总和，方便前端展示
            cart_num = 0
            for val in cart_dict.values():
                cart_num += int(val)

            # 将(cart_dict)重新生成json字符串，方便写入到cookie
            cart_json = json.dumps(cart_dict)

            # 创建JsonResponse对象，该对象就是要响应的对象
            response = JsonResponse({'code': 0, 'message': '添加购物车成功', 'cart_num': cart_num})

            # 在响应前，设置cookie信息
            response.set_cookie('cart', cart_json)

            return response
